<template>
    <div class="son">
        <div>子组件</div>
        <span @click="emitFn">{{ id }}--{{ fromId }}</span>——————
        <span @click="ChangeSyncNum">{{ syncNum }}</span>
        <!-- <span>provide/inject: {{ provideValue }}</span>————— -->
        <div>provide/inject: {{ this.provideVal() }}</div>
        <div>ref/refs: {{ refValue }}</div>
        <span>$parent/$children: {{ parentChildrenValue }}</span>
        <button @click="changeParent">改变$parent</button>
    </div>
</template>

<script>
export default {
    // props:["id"],    //和下面那种写法不能同时存在，否则这句是不执行的，id是未定义的。
    //这种写法叫 props 的验证写法。当 prop 验证失败的时候，(开发环境构建版本的) Vue 将会产生一个控制台的警告。
    props:{     
        id: Number, //只设置值的类型。
        syncNum:{
            // type: Number,   // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
            // String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定义构造函数, 
            type: [Number,String],   // 设置多个可能的类型
            default: 1,              // 对象或数组的默认值必须从一个工厂函数返回。
            required: true,          // 设置这个属性是否是必须传的
            validator: function(value){  // 设置一个验证函数，该 prop 的值作为唯一的参数代入，如果返回true，则验证通过，否则验证失败, 控制台抛出警告
                return value > 0 || value !== '';
            }
        }
    },

    data(){
        return{
            // id:0,    //如果data中有和props相同的数据，以props数据优先，并且控制台发出警告
            fromId: this.id,
            refValue: "refValue",
            parentChildrenValue: "parentChildrenValue",
        }
    },

    // inject:["provideValue"],
    // inject: {provideValue: "provideValue"},      //为什么要这样子写？
    inject: {    //这样写可以做到响应式。provideVal是别名
        provideVal: {
            from: "provideValue", 
            default: ()=>{}
        }
    },
    
    methods: {
        emitFn(){
            // console.log(this.$props);
            this.fromId = 11//可以在data中拷贝一份父组件传过来的值，就可以直接修改了。也可以在computed中
            // this.$emit("myEvent", 1);//触发的事件名一定要和v-on监听的一样，不能用小驼峰触发短横线分割名
            this.$emit("my-event", 1);
        },
        ChangeSyncNum(){
            this.$emit("update:syncNum", "jldkf")   //$emit的另一种写法
        },
        changeParent(){
            this.$parent.id += 1    // 这样子改变父组件传给子组件的值并不会触发子组件的响应式更新。
        }
    },

    // mounted(){
    //     // 选项Api数据的优先级排序
    //     console.log(this.id);
    // },
    destroyed(){
        console.log("卸载了！！！");
    },
    beforeRouteEnter(){
        console.log("beforeRouteEnter");
    },
    beforeRouteLeave(){
        console.log("beforeRouteLeave");
    }
}
</script>

<style scoped>
    .son{
        background-color: skyblue;
    }
</style>